#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <termios.h>
#include "qisr.h"
#include "msp_cmn.h"
#include "msp_errors.h"
#include "speech_recognizer.h"
#include "ros/ros.h"
#include "std_msgs/String.h"

#define BUFFER_SIZE 8192

// 全局状态控制
volatile int resultFlag = 0;
volatile int restartFlag = 0;
char* g_result = NULL;
size_t g_buffersize = BUFFER_SIZE;
struct speech_rec* global_iat = NULL;
volatile int exitFlag = 0;  // 退出标志

// 互斥锁保护共享变量
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// 识别结果回调
void on_result(const char *result, char is_last) {
    pthread_mutex_lock(&lock);
    if (result) {
        size_t result_len = strlen(result);
        size_t current_len = g_result ? strlen(g_result) : 0;
        
        // 动态扩展缓冲区
        if (current_len + result_len + 1 > g_buffersize) {
            g_buffersize += BUFFER_SIZE;
            char* new_buf = (char*)realloc(g_result, g_buffersize);
            if (!new_buf) {
                ROS_ERROR("Memory reallocation failed");
                pthread_mutex_unlock(&lock);
                return;
            }
            g_result = new_buf;
        }
        
        // 追加结果
        if (current_len == 0) {
            strcpy(g_result, result);
        } else {
            strcat(g_result, result);
        }
        
        // 只有最后一段才设置标志位
        if (is_last) {
            resultFlag = 1;
            ROS_INFO("Final Result: %s", g_result);
        }
    }
    pthread_mutex_unlock(&lock);
}

// 语音开始回调
void on_speech_begin() {
    pthread_mutex_lock(&lock);
    if (g_result) {
        free(g_result);
        g_result = NULL;
    }
    g_result = (char*)malloc(BUFFER_SIZE);
    if (g_result) {
        memset(g_result, 0, BUFFER_SIZE);
        g_buffersize = BUFFER_SIZE;
        ROS_DEBUG("New recording started");
    } else {
        ROS_ERROR("Memory allocation failed");
    }
    pthread_mutex_unlock(&lock);
}

// 语音结束回调
void on_speech_end(int reason) {
    if (reason == END_REASON_VAD_DETECT) {
        ROS_DEBUG("Voice activity end detected, preparing restart");
        restartFlag = 1;  // 设置重启标志
    } else {
        ROS_WARN("Speech ended with reason: %d", reason);
    }
}

// 持续监听管理函数 (在独立线程中运行)
void* recognition_control(void* arg) {
    const char* params = (const char*)arg;
    struct speech_rec_notifier notifier = {on_result, on_speech_begin, on_speech_end};

    while (!exitFlag) {
        try {
            // 初始化识别器
            global_iat = (struct speech_rec*)malloc(sizeof(struct speech_rec));
            int ret = sr_init(global_iat, params, SR_MIC, &notifier);
            if (ret != 0) {
                ROS_ERROR("Recognizer init failed: %d, retrying...", ret);
                free(global_iat);
                global_iat = NULL;
                sleep(1);
                continue;
            }

            // 启动监听会话
            ret = sr_start_listening(global_iat);
            if (ret != 0) {
                ROS_ERROR("Start listening failed: %d", ret);
                sr_uninit(global_iat);
                free(global_iat);
                global_iat = NULL;
                usleep(500000);
                continue;
            }

            ROS_INFO("Listening... (Press Ctrl+C to stop)");
            
            // 等待重启信号
            while (!exitFlag && !restartFlag) {
                usleep(100000);  // 100ms检查间隔
            }

            // 清理当前会话
            sr_stop_listening(global_iat);
            sr_uninit(global_iat);
            free(global_iat);
            global_iat = NULL;
            restartFlag = 0;  // 重置标志
            
            ROS_DEBUG("Restarting recognition...");
        } catch (const std::exception& e) {
            ROS_ERROR("Recognition exception: %s", e.what());
            if (global_iat) {
                sr_stop_listening(global_iat);
                sr_uninit(global_iat);
                free(global_iat);
                global_iat = NULL;
            }
            usleep(1000000); // 等待1秒后重试
        }
    }
    return NULL;
}

int main(int argc, char** argv) {
    ros::init(argc, argv, "voice_recognizer");
    ros::NodeHandle nh;
    ros::Publisher pub = nh.advertise<std_msgs::String>("/iat_text", 1000);
    
    // 等待订阅者
    while (pub.getNumSubscribers() == 0 && ros::ok()) {
        ROS_INFO("Waiting for /iat_text subscriber...");
        ros::Duration(0.5).sleep();
    }
    ROS_INFO("Ready, topic: %s", pub.getTopic().c_str());
    
    // 登录讯飞平台
    const char* login_params = "appid = 21cc2eff, work_dir = .";
    int ret = MSPLogin(NULL, NULL, login_params);
    if (ret != MSP_SUCCESS) {
        ROS_FATAL("MSP Login failed: %d", ret);
        return -1;
    }

    // 会话参数配置
    const char* session_params = 
        "sub = iat, domain = iat, "
        "language = zh_cn, accent = mandarin, "
        "sample_rate = 16000, "
        "vad_eos = 2000, "  // 2秒静音自动停止
        "vad_bos = 3000, "  // 3秒超时等待语音开始
        "result_type = plain, result_encoding = utf8";

    // 启动识别控制线程
    pthread_t recog_thread;
    pthread_create(&recog_thread, NULL, recognition_control, (void*)session_params);

    // 结果处理主循环
    ros::Rate rate(20);  // 20Hz处理频率
    while (ros::ok()) {
        if (resultFlag) {
            pthread_mutex_lock(&lock);
            
            if (g_result) {
                std_msgs::String msg;
                msg.data = std::string(g_result);
                pub.publish(msg);
                ROS_INFO("Published: %s", msg.data.c_str());
                
                free(g_result);
                g_result = NULL;
            }
            resultFlag = 0;
            
            pthread_mutex_unlock(&lock);
        }
        ros::spinOnce();
        rate.sleep();
    }

    // 设置退出标志并等待线程结束
    exitFlag = 1;
    pthread_join(recog_thread, NULL);

    // 清理资源
    if (global_iat) {
        sr_stop_listening(global_iat);
        sr_uninit(global_iat);
        free(global_iat);
    }
    MSPLogout();
    
    pthread_mutex_lock(&lock);
    if (g_result) free(g_result);
    pthread_mutex_unlock(&lock);
    
    pthread_mutex_destroy(&lock);
    
    ROS_INFO("Voice recognizer shutdown");
    return 0;
}
